"""
完整的CodeQL工作流和代码推荐系统演示
展示从source到sink的完整分析流程
"""

import os
import sys
import time
from pathlib import Path

# 添加当前目录到Python路径
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

from codeql_workflow import CodeQLWorkflow
from enhanced_code_recommender import EnhancedCodeRecommender
from code_recommender import get_driver
from neo4j_loader import import_callgraph_csv


def demo_complete_workflow():
    """演示完整的CodeQL工作流"""
    print("🚀 CodeQL完整工作流演示")
    print("=" * 60)
    
    # 假设的源代码目录（你需要替换为实际的源代码路径）
    source_dir = input("请输入源代码目录路径: ").strip()
    if not source_dir or not os.path.exists(source_dir):
        print("❌ 源代码目录不存在，使用示例目录")
        source_dir = "/path/to/your/source/code"  # 替换为实际路径
    
    try:
        # 1. 创建CodeQL工作流
        workflow = CodeQLWorkflow()
        
        # 2. 运行完整工作流
        print("\n📊 步骤1: 运行CodeQL分析...")
        results = workflow.run_workflow(
            source_dir=source_dir,
            language="cpp",
            queries=[
                "CallGraph.ql",
                "DataFlowAnalysis.ql",
                "ControlFlowAnalysis.ql", 
                "SecurityVulnerabilities.ql"
            ]
        )
        
        if not results:
            print("❌ CodeQL分析失败，跳过后续步骤")
            return
        
        # 3. 分析结果
        print("\n📈 步骤2: 分析查询结果...")
        analysis = workflow.analyze_results(results)
        
        # 4. 生成报告
        print("\n📝 步骤3: 生成分析报告...")
        report_file = workflow.generate_report(analysis)
        
        print(f"✅ CodeQL工作流完成！报告: {report_file}")
        return results, analysis
        
    except Exception as e:
        print(f"❌ CodeQL工作流执行失败: {e}")
        return None, None


def demo_neo4j_integration(results):
    """演示Neo4j集成"""
    print("\n🔗 Neo4j集成演示")
    print("=" * 60)
    
    if not results or "CallGraph.ql" not in results:
        print("❌ 没有调用图数据，跳过Neo4j集成")
        return False
    
    try:
        # 导入调用图数据到Neo4j
        callgraph_file = results["CallGraph.ql"]
        print(f"📥 导入调用图数据: {callgraph_file}")
        
        driver = get_driver()
        import_callgraph_csv(driver, callgraph_file)
        driver.close()
        
        print("✅ Neo4j数据导入成功")
        return True
        
    except Exception as e:
        print(f"❌ Neo4j集成失败: {e}")
        return False


def demo_enhanced_recommendations():
    """演示增强版代码推荐"""
    print("\n🎯 增强版代码推荐演示")
    print("=" * 60)
    
    try:
        # 创建增强推荐器
        driver = get_driver()
        recommender = EnhancedCodeRecommender(driver)
        
        # 测试函数
        test_functions = ["main", "process", "init", "handle"]
        
        for func_name in test_functions:
            print(f"\n🔍 分析函数: '{func_name}'")
            
            # 获取智能推荐
            user_context = {
                "prefer_security": True,
                "current_file": "src/main.cpp",
                "current_line": 10
            }
            
            smart_recs = recommender.get_smart_recommendations(func_name, user_context)
            
            if smart_recs["top_recommendations"]:
                print(f"   🏆 顶级推荐:")
                for i, rec in enumerate(smart_recs["top_recommendations"][:3], 1):
                    print(f"      {i}. {rec['function_name']} (分数: {rec['score']:.2f})")
                    print(f"         类型: {rec['recommendation_type']}")
                    print(f"         理由: {rec['reason']}")
            else:
                print(f"   ❌ 没有找到推荐")
        
        driver.close()
        return True
        
    except Exception as e:
        print(f"❌ 增强推荐演示失败: {e}")
        return False


def demo_security_analysis(results):
    """演示安全分析"""
    print("\n🔒 安全分析演示")
    print("=" * 60)
    
    if not results or "SecurityVulnerabilities.ql" not in results:
        print("❌ 没有安全分析数据")
        return
    
    security_file = results["SecurityVulnerabilities.ql"]
    print(f"📊 安全分析结果: {security_file}")
    
    try:
        import csv
        with open(security_file, 'r', encoding='utf-8') as f:
            reader = csv.DictReader(f)
            vulnerabilities = list(reader)
        
        if vulnerabilities:
            print(f"🚨 发现 {len(vulnerabilities)} 个安全漏洞:")
            
            # 按严重程度分组
            by_severity = {}
            for vuln in vulnerabilities:
                severity = vuln.get('severity', 'Unknown')
                if severity not in by_severity:
                    by_severity[severity] = []
                by_severity[severity].append(vuln)
            
            for severity, vulns in by_severity.items():
                print(f"\n   {severity} 级别: {len(vulns)} 个")
                for vuln in vulns[:3]:  # 显示前3个
                    print(f"      - {vuln.get('vulnerability_type', 'Unknown')}")
                    print(f"        位置: {vuln.get('source_location', 'Unknown')}")
                    print(f"        描述: {vuln.get('description', 'No description')}")
        else:
            print("✅ 未发现安全漏洞")
    
    except Exception as e:
        print(f"❌ 安全分析失败: {e}")


def demo_dataflow_analysis(results):
    """演示数据流分析"""
    print("\n🌊 数据流分析演示")
    print("=" * 60)
    
    if not results or "DataFlowAnalysis.ql" not in results:
        print("❌ 没有数据流分析数据")
        return
    
    dataflow_file = results["DataFlowAnalysis.ql"]
    print(f"📊 数据流分析结果: {dataflow_file}")
    
    try:
        import csv
        with open(dataflow_file, 'r', encoding='utf-8') as f:
            reader = csv.DictReader(f)
            flows = list(reader)
        
        if flows:
            print(f"🌊 发现 {len(flows)} 条数据流:")
            
            # 按流类型分组
            by_type = {}
            for flow in flows:
                flow_type = flow.get('flow_path', 'Unknown')
                if flow_type not in by_type:
                    by_type[flow_type] = []
                by_type[flow_type].append(flow)
            
            for flow_type, flow_list in by_type.items():
                print(f"\n   {flow_type}: {len(flow_list)} 条")
                for flow in flow_list[:2]:  # 显示前2条
                    print(f"      源: {flow.get('source_location', 'Unknown')}")
                    print(f"      汇: {flow.get('sink_location', 'Unknown')}")
        else:
            print("✅ 未发现数据流")
    
    except Exception as e:
        print(f"❌ 数据流分析失败: {e}")


def main():
    """主演示函数"""
    print("🎯 CodeQL工作流和代码推荐系统完整演示")
    print("=" * 80)
    
    # 检查环境
    print("🔍 检查环境...")
    
    # 检查Neo4j连接
    try:
        driver = get_driver()
        with driver.session() as session:
            result = session.run("MATCH (f:Function) RETURN count(f) as count LIMIT 1")
            count = result.single()["count"]
            print(f"✅ Neo4j连接正常，包含 {count} 个函数")
        driver.close()
    except Exception as e:
        print(f"❌ Neo4j连接失败: {e}")
        print("请确保Neo4j服务正在运行")
        return
    
    # 演示菜单
    while True:
        print("\n" + "=" * 60)
        print("🎯 演示菜单")
        print("=" * 60)
        print("1. 运行完整CodeQL工作流")
        print("2. 演示增强版代码推荐")
        print("3. 演示安全分析")
        print("4. 演示数据流分析")
        print("5. 运行所有演示")
        print("6. 退出")
        print("-" * 60)
        
        try:
            choice = input("请选择演示 (1-6): ").strip()
            
            if choice == '1':
                results, analysis = demo_complete_workflow()
                if results:
                    demo_neo4j_integration(results)
            
            elif choice == '2':
                demo_enhanced_recommendations()
            
            elif choice == '3':
                # 需要先运行CodeQL工作流
                print("⚠️  需要先运行CodeQL工作流获取安全分析数据")
                run_workflow = input("是否现在运行? (y/n): ").strip().lower()
                if run_workflow == 'y':
                    results, analysis = demo_complete_workflow()
                    if results:
                        demo_security_analysis(results)
            
            elif choice == '4':
                # 需要先运行CodeQL工作流
                print("⚠️  需要先运行CodeQL工作流获取数据流分析数据")
                run_workflow = input("是否现在运行? (y/n): ").strip().lower()
                if run_workflow == 'y':
                    results, analysis = demo_complete_workflow()
                    if results:
                        demo_dataflow_analysis(results)
            
            elif choice == '5':
                print("🚀 运行所有演示...")
                results, analysis = demo_complete_workflow()
                if results:
                    demo_neo4j_integration(results)
                    demo_enhanced_recommendations()
                    demo_security_analysis(results)
                    demo_dataflow_analysis(results)
            
            elif choice == '6':
                print("👋 再见！")
                break
            
            else:
                print("❌ 无效选择，请输入 1-6")
        
        except KeyboardInterrupt:
            print("\n👋 再见！")
            break
        except Exception as e:
            print(f"❌ 演示执行失败: {e}")


if __name__ == "__main__":
    main()
